import Player from "../Player/Player";
import AttackRangeView from "./AttackRangeView";
import EquipView from "./EquipView";
import MonsterView from "./MonsterView";
import gTipManager from "../TipManager";
import gGameManager from "../GameManager";
import GameView from "./GameView";

const { ccclass, property } = cc._decorator;

@ccclass
export default class PlayerView extends cc.Component {

    m_player: Player = null;

    @property
    speed: number = 100;

    @property(AttackRangeView)
    atk_range: AttackRangeView = null;

    anim: cc.Animation = null;

    body: cc.RigidBody = null;

    //是否正在移动
    is_moving: boolean = false;
    //当前需要移动的总时间
    move_time: number = 0;
    //x方向速度
    vx: number = 0;
    //y方向速度
    vy: number = 0;

    //当前方向
    dir: number = 0;
    //状态
    state: string = "stand";
    //是否开始战斗
    is_atk: boolean = false;
    //是否初始化完毕
    inited: boolean = false;

    onLoad(){
        this.body = this.node.getComponent(cc.RigidBody);
        this.anim = this.node.getComponent(cc.Animation);
    }

    attack(){
        for(let i = this.atk_range.coll_nodes.length-1; i >= 0; --i){
            let node = this.atk_range.coll_nodes[i];
            if(!node){
                this.atk_range.coll_nodes.splice(i, 1);
                continue;
            }
            let monsterView = node.getComponent(MonsterView);
            if(monsterView){
                this.m_player.attack(monsterView.m_monster);
            }
        }
    }

    onAttack(hp: number){
        gTipManager.instance().showTip(`-${hp}`, cc.Color.RED, this.node);
    }

    onDead(){
        //死亡处理
        console.log("英雄死亡");
        this.unscheduleAllCallbacks();
        GameView.instance().showMapList();
        this.inited = false;
        this.is_atk = false;
    }

    public startAttack():void{
        if(this.is_atk){
            return;
        }
        this.schedule(this.attack, 0.5);
        this.is_atk = true;
    }

    public stopAttack():void{
        this.unschedule(this.attack);
        this.is_atk = false;
    }

    init(player: Player){
        if(!player){
            return;
        }

        this.reset();

        this.m_player = player;
        this.m_player.m_playerView = this;

        //加载动画
        cc.resources.loadDir(`animation/role_${this.m_player.m_roleId}`, cc.AnimationClip, (err, assets) => {
            if(!err){
                assets.forEach((val, key) => {
                    let clip = <cc.AnimationClip>val;
                    this.anim.addClip(clip);
                });
                this.inited = true;
                this.updateAnim("stand", 1);
            }
        });
    }

    reset(){
        this.anim.stop();
        let clips = this.anim.getClips();
        for(let i = clips.length-1; i >= 0; --i){
            //clips[i].decRef();
            this.anim.removeClip(clips[i]);
        }

        this.move_time = 0;
        this.m_player = null;
        this.state = "stand";
        this.dir = 0;
        this.is_atk = false;
    }

    //刷新动画
    updateAnim(state: string, dir: number){
        if(state === this.state && this.dir === dir){
            return;
        }
        this.state = state;
        this.dir = dir;
        let animName = `role_${this.m_player.m_roleId}_${this.state}_${this.dir}`;
        let animState = this.anim.play(animName);
        animState.wrapMode = cc.WrapMode.Loop;
        if(state == "run"){
            animState.speed = this.speed / 100;
            this.stopAttack();
        }
        else if(state == "stand"){
            this.startAttack();
        }
    }

    moveToTarget(dst: cc.Vec2){
        if(!this.inited){
            return;
        }

        let src = this.node.getPosition();
        let dir = dst.sub(src);
        let len = dir.mag();
        if(len <= 0){
            return;
        }

        //时间=路程/速度
        this.move_time = len / this.speed;

        //x速度=x长度/时间
        this.vx = dir.x / this.move_time
        //y速度=y长度/时间
        this.vy = dir.y / this.move_time;

        this.body.linearVelocity = cc.v2(this.vx, this.vy);

        //计算移动方向
        let radian = dir.signAngle(cc.v2(0, -1));
        let degree = Math.floor(cc.misc.radiansToDegrees(radian));
        //console.log("degree:", degree, Math.round(degree / 45));
        let d = degree == 0 ? 0 : Math.round(degree / 45);
        d = d < 0 ? 8 + d + 1 : d + 1;
        //开始播放相应奔跑动画
        this.updateAnim("run", d);

        this.is_moving = true;
    }

    update(dt) {
        if(!this.is_moving){
            return;
        }
        if(this.move_time <= 0){
            this.body.linearVelocity = cc.v2(0,0);
            //停止奔跑动画，播放站立动画
            this.updateAnim("stand", this.dir);
            this.is_moving = false;
            return;
        }

        if(this.move_time < dt){
            //最后那一段需要重新计算
            this.vx *= this.move_time / dt;
            this.vy *= this.move_time / dt;
            this.body.linearVelocity = cc.v2(this.vx, this.vy);
        }

        this.move_time -= dt;

        // this.node.x += this.vx * dt;
        // this.node.y += this.vy * dt;
    }
}
